package edu.vt.tcga.methylation.level2;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.Transaction;

import edu.vt.tcga.HibernateUtil;

public class MethylationSignalIntensityTable {

	private List<MethylationSignalIntensity> values;

	// Accessor methods
	public List<MethylationSignalIntensity> getValues() {
		return values;
	}
	public void setValues(List<MethylationSignalIntensity> values) {
		this.values = values;
	}

	public MethylationSignalIntensityTable(){
		values = new ArrayList<MethylationSignalIntensity>();
	}

	public MethylationSignalIntensityTable(String filename){
		this();
		this.loadFromFile(filename);
	}

	
	// Utility functions
	public void loadFromFile(String filename){
		
		// Get current time
		long start = System.currentTimeMillis();
		
		System.out.println("Attempting to load Methylation level 2 file: " + filename);
		
		try {
			BufferedReader in  = new BufferedReader(new FileReader(filename));
			String line = "";
			String delims = "\t";
	
			// Load MethylationSignalIntensity
			// Get the barcode values in the file.
			List<String> barcodeValues = new ArrayList<String>();
			line = in.readLine();
			String[] tokens = line.split(delims);

			for(int i=0; i<tokens.length; i++){
				barcodeValues.add(tokens[i]);
			}
			
//			List<String> normalizationValues = new ArrayList<String>();
			line = in.readLine();
//			tokens = line.split(delims);
//
//			for(int i=0; i<tokens.length; i++){
//				normalizationValues.add(tokens[i]);
//			}
			
			while( (line = in.readLine()) != null){
				tokens = line.split(delims);

				String compositeElement = tokens[0];
				double betaValue = 0.0;
				int mSignal = 0;
				int uSignal = 0;

				for(int i=1; i< tokens.length; i++){
					
					String barcode = barcodeValues.get(i);
					int n = i-1;
					
					if(n % 3 == 0){	// Beta Value
						try{
							betaValue = Double.parseDouble(tokens[i]);
						}
						catch(NumberFormatException ne){
							System.out.println("Could not format beta value. Value read in as " + 
									tokens[i] +
									". Setting to 0.0.");
						}
					}
					else if(n % 2 == 0){	// Methylated Signal Intensity
						try{
							mSignal = Integer.parseInt(tokens[i]);
						}
						catch(NumberFormatException ne){
							System.out.println("Could not format methylated signal value. Value read in as " + 
									tokens[i] +
									". Setting to 0.0.");
						}
					}
					else{	// Un-Methylated Signal Intensity
						try{
							uSignal = Integer.parseInt(tokens[i]);
						}
						catch(NumberFormatException ne){
							System.out.println("Could not format unmethylated signal value. Value read in as " + 
									tokens[i] +
									". Setting to 0.0.");
						}
					}
					
					MethylationSignalIntensity msi = new MethylationSignalIntensity(compositeElement,
							barcode,
							betaValue, 
							mSignal,
							uSignal);

					values.add(msi);
				}
			}
		}
		catch (FileNotFoundException e) {
			e.printStackTrace();
		} 
		catch (IOException e) {
			e.printStackTrace();
		}
		
		// Get elapsed time in milliseconds
		long elapsedTimeMillis = System.currentTimeMillis()-start;
		double seconds = elapsedTimeMillis / 1000.0;
		
		System.out.println("Loaded Methylation level 2 data in " + seconds + " seconds");
	}

	// Save the class out to the database
	public void saveToDatabase(){
		
		// Get current time
		long start = System.currentTimeMillis();
				
		try{
			Session session = HibernateUtil.getSession();
	        Transaction tx = session.beginTransaction();
	        int i = 0;
	        
	        for(MethylationSignalIntensity msi : this.getValues()){
	        	session.save(msi);
		        
	            if ( i % 20 == 0 ) { //Same as the JDBC batch size
	                //flush a batch of inserts and release memory:
	                session.flush();
	                session.clear();
	            }
	            
		        i++;
	        }
	        
	        tx.commit();
	        session.close();
		}
		catch(Exception e){
			e.printStackTrace();
		}

		// Get elapsed time in milliseconds
		long elapsedTimeMillis = System.currentTimeMillis()-start;
		double seconds = elapsedTimeMillis / 1000.0;
		
		System.out.println("Saved Methylation level 2 data in " + seconds + " seconds");
	}
}
